package com.spark.incoicings.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spark.incoicings.dao.*;
import com.spark.incoicings.service.InboundDetailService;
import com.spark.invoicings.entity.*;
import com.spark.invoicings.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class InboundDetailServiceImpl
        extends ServiceImpl<InboundDetailMapper, InboundDetail>
        implements InboundDetailService {

    @Resource
    private InboundDetailMapper inboundDetailMapper;

    @Resource
    private ProductMapper productMapper;

    @Resource
    private PurchaseDetailsMapper purchaseDetailMapper;

    @Resource
    private OrderDetailMapper orderDetailMapper;

    @Resource
    private ReceiptDetailMapper receiptDetailMapper;

    @Resource
    private ReturnDetailMapper returnDetailMapper;

    @Resource
    private WarehouseReceiptMapper warehouseReceiptMapper;

    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 根据id回显入库单明细数据
     * @param id
     * @return
     */
    @Override
    public InboundDetail selectInboundDetailByInboundId(Integer id) {
        InboundDetail inboundDetail = inboundDetailMapper.selectInboundDetailByInboundId(id);
        Product product = productMapper.selectProductById(inboundDetail.getProductId());
        OrderDetail orderDetail = orderDetailMapper.selectById(inboundDetail.getOrderDetailId());
        ReturnDetail returnDetail = returnDetailMapper.selectById(inboundDetail.getReturnDetailId());
        ReceiptDetail receiptDetail = receiptDetailMapper.selectById(inboundDetail.getReceiptDetailId());
        PurchaseDetail purchaseDetail = purchaseDetailMapper.selectById(inboundDetail.getPurchaseDetailId());
        inboundDetail.setProduct(product);
        inboundDetail.setOrderDetail(orderDetail);
        inboundDetail.setReturnDetail(returnDetail);
        inboundDetail.setReceiptDetail(receiptDetail);
        inboundDetail.setPurchaseDetail(purchaseDetail);
        return inboundDetail;
    }

    /**
     * 保存入库明细单
     * @param inboundDetail
     * @return
     */
    @Transactional
    @Override
    public Result addInboundDetail(InboundDetail inboundDetail) {
        inboundDetailMapper.insert(inboundDetail);
        Product product = productMapper.selectProductById(inboundDetail.getProductId());
        // 产品库存
        product.setCurrentInventory(product.getCurrentInventory() + inboundDetail.getInboundQuantity());
        productMapper.updateById(product);
        return Result.success(200, "success", inboundDetail.getInboundDetailId());
    }

    /**
     * 保存和更新入库单明细数据加载
     * @return
     */
    @Override
    public Result selectInboundDetailSave() {
        Map<String, Object> data = new HashMap<>();
        // 尝试从 Redis 中获取缓存数据
        Map<String, Object> cachedData = redisTemplate.opsForHash().entries("your_cache_key");
        if (!cachedData.isEmpty()) {
            // 如果缓存中有数据，则直接返回缓存数据
            return Result.success(200, "success", cachedData);
        }
        // 如果缓存中没有数据，则从数据库中查询数据

        // 采购明细
        List<PurchaseDetail> purchaseDetailList = purchaseDetailMapper.selectPurchaseDetailAll(new HashMap<>());
        // 订单明细
        List<OrderDetail> orderDetailList = orderDetailMapper.selectOrderDetails();
        // 退货明细
        List<ReturnDetail> returnDetailList = returnDetailMapper.selectList(null);
        // 到货明细
        List<ReceiptDetail> receiptDetailList = receiptDetailMapper.selectReceiptDetailAll(null);
        // 将查询到的数据存入 Redis 缓存，设置缓存有效时间为1小时
        data.put("purchaseDetailList", purchaseDetailList);
        data.put("orderDetailList", orderDetailList);
        data.put("receiptDetailList", receiptDetailList);
        data.put("returnDetailList", returnDetailList);

        redisTemplate.opsForHash().putAll("your_cache_key", data);
        redisTemplate.expire("your_cache_key", 1, TimeUnit.HOURS);
        // 返回查询结果
        return Result.success(200, "success", data);
    }

    /**
     * 查询所有入库单明细
     * @param map
     * @return
     */
    @Override
    public List<InboundDetail> selectInboundDetailAll(Map<String, Object> map) {
        List<InboundDetail> list = inboundDetailMapper.selectInboundDetailAll(map);
        // 根据id查询对象进行set
        list.forEach(inboundDetail -> {
            Product product = productMapper.selectProductById(inboundDetail.getProductId());
            OrderDetail orderDetail = orderDetailMapper.selectById(inboundDetail.getOrderDetailId());
            ReturnDetail returnDetail = returnDetailMapper.selectById(inboundDetail.getReturnDetailId());
            ReceiptDetail receiptDetail = receiptDetailMapper.selectById(inboundDetail.getReceiptDetailId());
            PurchaseDetail purchaseDetail = purchaseDetailMapper.selectById(inboundDetail.getPurchaseDetailId());
            inboundDetail.setProduct(product);
            inboundDetail.setOrderDetail(orderDetail);
            inboundDetail.setReturnDetail(returnDetail);
            inboundDetail.setReceiptDetail(receiptDetail);
            inboundDetail.setPurchaseDetail(purchaseDetail);
        });
        return list;
    }

    /**
     * 更新入库单明细
     * @param inboundDetail
     * @return
     */
    @Transactional
    @Override
    public Result updateInboundDetail(InboundDetail inboundDetail) {
        inboundDetailMapper.updateById(inboundDetail);
        int inboundQuantity = 0;
        WarehouseReceipt warehouseReceipt = warehouseReceiptMapper.selectWarehouseReceiptById(inboundDetail.getInboundOrderId());
        for (InboundDetail detail : warehouseReceipt.getInboundDetailList()) {
            inboundQuantity += detail.getInboundQuantity();
        }
        warehouseReceipt.setTotalQuantity(inboundQuantity);
        warehouseReceiptMapper.updateById(warehouseReceipt);
        Product product = productMapper.selectProductById(inboundDetail.getProductId());
        // 产品库存
        product.setCurrentInventory(product.getCurrentInventory() + inboundDetail.getInboundQuantity());
        productMapper.updateById(product);
        return Result.success(200, "success", inboundDetail.getInboundDetailId());
    }

}
